package com.example.demo.springmvc.principle.utils;

import java.io.File;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 包扫描类，获取所有.class文件字节码对象
 * 由basePackage(如:com.example.swap.springmvc.principle)得到这个包下的所有.class文件的全限定名，
 * 和Class对象用一个Map容器装载。
 *
 * @author: htc
 * @date: Created in 17:08 2019/2/20.
 */
public class ClassScanner {
    /**
     * 扫描class文件
     *
     * @param basePackage
     * @return
     */
    public static Map<String, Class<?>> scannerClass(String basePackage) {
        Map<String, Class<?>> result = new HashMap<>();
        //把 com.example.swap.springmvc.principle 换成  com/example/swap/springmvc/principle  再；类加载读取文件
        String basePath = basePackage.replaceAll("\\.", "/");
        try {
            //得到文件的绝对地址
            String rootPath = ClassScanner.class.getClassLoader().getResource(basePath).getPath();
            if (rootPath != null) {
                rootPath = rootPath.substring(rootPath.indexOf(basePath));
            }

            Enumeration<URL> enumeration = ClassScanner.class.getClassLoader().getResources(basePath);
            while (enumeration.hasMoreElements()) {
                URL url = enumeration.nextElement();
                if (url.getProtocol().equals("file")) {
                    File file = new File(url.getPath().substring(1));
                    scannerFile(file, rootPath, result);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 扫描文件
     *
     * @param folder
     * @param rootPath
     * @param classes
     */
    private static void scannerFile(File folder, String rootPath, Map<String, Class<?>> classes) {
        try {
            File[] files = folder.listFiles();
            for (int i = 0; i < files.length && files != null; i++) {
                File file = files[i];
                if (file.isDirectory()) {
                    scannerFile(file, rootPath + file.getName() + "/", classes);
                } else {
                    if (file.getName().endsWith(".class")) {
                        String className = (rootPath + "/" + file.getName()).replaceAll("/", ".");
                        //去掉扩展名得到全限定民
                        className = className.substring(0, className.indexOf(".class"));
                        //Map容器存储全限定名和class
                        classes.put(className, Class.forName(className));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        scannerClass("com.example.swap.springmvc.principle.utils");
    }
}
